package com.hzlj.position.locate.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fz.common.base.core.JsonUtils;
import com.fz.common.dict.annotation.DictConvert;
import com.hzlj.position.locate.common.dto.differentiationData.DifferentiationDataAddDTO;
import com.hzlj.position.locate.common.dto.differentiationData.DifferentiationDataQueryParamDTO;
import com.hzlj.position.locate.common.dto.differentiationData.DifferentiationDataQueryResultDTO;
import com.hzlj.position.locate.common.enums.DifferentiationDataType;
import com.hzlj.position.locate.common.model.DifferentiationData;
import com.hzlj.position.locate.converter.DifferentiationDataConverter;
import com.hzlj.position.locate.dao.DifferentiationDataDao;
import com.hzlj.position.locate.differentiation.DifferentiationService;
import com.hzlj.position.locate.service.DifferentiationConfigService;
import com.hzlj.position.locate.service.DifferentiationDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.hzlj.position.config.config.IdConfig.POSITION_ID_GEN;

/**
 * 独立业务-数据(DifferentiationData)表服务接口
 *
 * @author makejava
 * @date 2024-08-16 15:13:19
 */
@Slf4j
@Service
public class DifferentiationDataServiceImpl implements DifferentiationDataService {
    @Resource
    private DifferentiationDataDao differentiationDataDao;
    @Resource
    private DifferentiationConfigService differentiationConfigService;
    @Resource
    private RedisTemplate<String, Integer> redisTemplate;
    private final static String LOCATE_JOB_DELAY_KEY = "locate:job:delay:%s:%s";


    /**
     * 新增数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDifferentiationData(DifferentiationDataAddDTO dto) {
        //是否需要判断有重复情况
        DifferentiationData differentiationData = DifferentiationDataConverter.from(dto);
        //新增数据
        differentiationData.setId(POSITION_ID_GEN.nextIdStr());
        this.differentiationDataDao.save(differentiationData);
        log.info("保存独立业务数据:differentiationData={}", differentiationData);
    }

    @Override
    public int handle() {
        List<DifferentiationDataQueryResultDTO> datas = this.listDifferentiationData(new DifferentiationDataQueryParamDTO().setHandleTime(new Date()));
        if (ObjectUtil.isEmpty(datas)) {
            return 0;
        }

        for (DifferentiationDataQueryResultDTO data : datas) {
            try {
                log.warn("处理独立业务数据:type={},jgCode={},data={}", data.getType(), data.getJgCode(), JsonUtils.obj2json(data));
                DifferentiationService service = differentiationConfigService.getService(null, DifferentiationDataType.of(data.getType()), data.getJgCode());
                if (service == null) {
                    log.warn("处理独立业务数据出错,没有匹配到service:type={},jgCode={},data={}", data.getType(), data.getJgCode(), JsonUtils.obj2json(data));
                    continue;
                }
                service.handleDifferentiationData(data);
            } catch (Exception e) {
                log.error("处理独立业务数据出错:type={},jgCode={},data={}", data.getType(), data.getJgCode(), JsonUtils.obj2json(data), e);
            } finally {
                //处理完之后删除
                this.differentiationDataDao.removeById(data.getId());
            }
        }
        return datas.size();
    }

    /**
     * 设置调度缓存
     */
    public void setLocateJobDelay(String deviceCode,
                                  String channel,
                                  Integer delayMinutes) {
        String key = String.format(LOCATE_JOB_DELAY_KEY, deviceCode, channel);
        redisTemplate.opsForValue().set(
                key,
                delayMinutes,
                delayMinutes + 30,
                TimeUnit.MINUTES
        );
    }

    /**
     * 获取调度缓存
     */
    public Integer getLocateJobDelay(String deviceCode,
                                     String channel) {
        String key = String.format(LOCATE_JOB_DELAY_KEY, deviceCode, channel);
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public void removeLocateJobDelay(String deviceCode, String channel) {
        String key = String.format(LOCATE_JOB_DELAY_KEY, deviceCode, channel);
        redisTemplate.delete(key);
    }

    /**
     * 查询列表：不分页
     */
    @Override
    @DictConvert
    public List<DifferentiationDataQueryResultDTO> listDifferentiationData(DifferentiationDataQueryParamDTO dto) {
        return this.differentiationDataDao.listDifferentiationData(dto);
    }

}
